package com.eight.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: 生产二维码的工具类
 * @Author: Van.Planifolia
 * @CreateTime: 2023-02-24  19:51
 * @Version: 1.0
 */
public class QRCodeUtil {
    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;

    /**
     * 根据正文字符串生成BufferImage
     *
     * @param content 正文信息
     * @return 生产的BufferImage
     */
    public static BufferedImage produceImage(String content) {
        // 线程安全的HashMap
        ConcurrentHashMap<EncodeHintType, Object> hints = new ConcurrentHashMap<>();
        // 误差校验等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 设置编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 设置外边距
        hints.put(EncodeHintType.MARGIN, 1);

        BitMatrix bitMatrix = null;
        try {
            bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        // 设置图片的规格
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {
                assert bitMatrix != null;
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }

    /**
     * 根据Image对象生成Base64码
     *
     * @param image BufferImage对象
     * @return 生产的Base64值
     */
    public static String generateBase64(BufferedImage image) {
        // 构建字节数组输出流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 图片数据写入baos
            ImageIO.write(image, "png", baos);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 生成Base64,首先我们要获取Base64的Encoder内部工具方法
        Base64.Encoder encoder = Base64.getEncoder();
        // 调用encoder的encodeToString方法将Byte数组转成BaseCode字符串
        String baseCode = encoder.encodeToString(baos.toByteArray());
        return "data:image/png;base64," + baseCode;
    }

    /**
     * 将二维码保存到resource文件夹中
     *
     * @param image 生成的BufferedImage对象
     * @return 保存到本地的文件路径
     */
    public static String generateImage(BufferedImage image) {
        // 获取当前resource文件夹
        String path = Objects.requireNonNull(QRCodeUtil.class.getClassLoader().getResource("")).getPath() + "\\temp.png";
        try {
            // 直接生产图片文件
            ImageIO.write(image, "png", new File(path));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 保存的文件路径
        return path;
    }

}
